<template>
    <div class="input-group">
        <input class="form-control" readonly :placeholder="placeholder" />
        <span class="input-group-append">
            <button ref="uploadBtn" class="btn btn-outline-secondary"
                    type="button">Upload</button>
            <button type="button" @click="reset()" class="btn btn-outline-danger">X</button>
        </span>
        <div v-if="error" class="error-text" v-text="error"></div>
    </div>
</template>
<script>
import plupload from "plupload";

const uploaderDefaultOption = {
    runtimes: 'html5,html4',
    headers: {
        "x-oss-object-acl": "public-read"
    },
    multi_selection: false,
    url : 'http://oss.aliyuncs.com',
    filters : {
        mime_types: [],
        max_file_size : '1500mb'
    },
};

export default {
    name: "vue-plupload",
    props: {
        text: {
            type: String,
            default: "Upload"
        },
        options: {
            type: Object,
            default: () => {
                return {}
            }
        },
    },

    data() {
        return {
            filename: "",
            statusText: "",
            errorText: false,
            uploader: null
        }
    },

    computed:{
        placeholder() {
            return `${this.text}: ${this.filename} ${this.statusText}`;
        },
        error() {
            if (this.errorText) {
                return JSON.stringify(this.errorText);
            }

            return false;
        }
    },

    methods: {
        renderUI() {

            this.$nextTick(() => {

                if (this.uploader) {
                    return;
                }

                let self = this;

                let opt = Object.assign(uploaderDefaultOption, self.options, {
                    browse_button: self.$refs.uploadBtn,
                });

                let uploader = new plupload.Uploader(opt);
                this.uploader = uploader;

                uploader.bind("PostInit", (up) => {
                    self.$emit("init", up)
                });

                uploader.bind("FilesAdded", (up, files) => {
                    self.$emit("added", up, files);
                    this.errorText = false;

                    this.filename = files[0].name;
                    this.statusText = `added`
                });

                uploader.bind("UploadProgress", (up, file) => {
                    self.$emit("progress", up, file);

                    let speed = (up.total.bytesPerSec / 1024 / 1024).toFixed(2);
                    this.statusText = `uploading ${file.percent}% ${speed} M/S`
                });

                uploader.bind("FileUploaded", (up, file, result) => {
                    self.$emit("uploaded", up, file, result)
                    this.statusText = `done`
                });

                uploader.bind("Error", (up, err) => {
                    self.$emit("error", up, err);
                    this.errorText = err;
                });


                uploader.init();
            });
        },

        setErrorText(text) {
            this.errorText = text;
        },

        reset() {
            if (this.uploader) {
                this.uploader.stop();
                this.uploader.refresh();
            }
            this.filename = "";
            this.statusText = "";
        }
    },

    mounted() {
        this.renderUI();
    },

    updated() {
        this.renderUI();
    }
};
</script>
<style>
.error-text {
    color: red;
}
</style>